package client.tcp;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * This is the client end which communicate with the 
 * server. Every data to be saved or load must connect from
 * this class which connects to the ServerTCP class.
 * @author daniel
 */
public class ClientTCP {

	private Socket socket;
	private ObjectOutputStream dataOutput;
	private ObjectInputStream receive;

	/**
	 * Establishes the connection to the server
	 * To close the connection use the send method
	 * and send a parameter "exit" or the closeCon
	 * method
	 * @param hostname Name of the server
	 * @param port Port to the server
	 */
	public ClientTCP(String hostname, int port) throws UnknownHostException, IOException {
		socket = new Socket(hostname, port);
	}

	/**
	 * This method is used to send information to the
	 * server. See documentation, "Formatting strings 
	 * to send.txt" for formatting the strings.
	 */
	public synchronized Serializable send(Serializable objectSend) {
		if(socket == null || !socket.isConnected()) {
			System.err.println("ClientTCP::send: Socket not initialized when attempting to send");
			return null;
		}

		try {
			dataOutput = new ObjectOutputStream(socket.getOutputStream());
			dataOutput.writeObject(objectSend);

//			System.out.println("Sendt:: " + objectSend.getClass().getSimpleName());
//			
//			objectSend instanceof Mockup) {
//				System.out.println("Appointment : state : " + ((Mockup)objectSend).getState());
//				System.out.println("Appointment : sessionid : " + ((Mockup)objectSend).getSessionId());
//				System.out.println("Appointment : toString : " + ((Mockup)objectSend).toString());
//			}



		} catch (SocketException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			receive = new ObjectInputStream(socket.getInputStream());
			Serializable received = (Serializable)receive.readObject();
			return received;
			
		} catch (Exception e) {
			System.err.println("ClientTCP::receive: Error during receive");
			e.printStackTrace();
		}
		return null;
	}

	public boolean isConnected() {
		return socket.isConnected();	
	}

	/**
	 * Closes the connection to the server
	 */
	public void closeCon() {
		try {
			if(dataOutput != null)
				dataOutput.close();
			if(receive != null) 
				receive.close();
			if(!socket.isClosed())
				socket.close();
		} catch (Exception e) {
			System.err.println("ClientTCP::closeCon: Connection could not be closed... " + e);
		}
	}
}
